package com.wzdigit.wms.wms.service.mid;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.Queryer;
import com.wzdigit.wms.basic.client.request.postback.PostbackRequest;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.order.TrsnHeader;
import com.wzdigit.wms.basic.domain.transfer.GdnHeader;
import com.wzdigit.wms.basic.domain.transfer.TransferHeader;
import com.wzdigit.wms.basic.enums.AsnTypeEnum;
import com.wzdigit.wms.basic.enums.GdnTypeEnum;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.basic.mapper.core.mid.IfPostbackMapper;
import com.wzdigit.wms.basic.mapper.core.order.AsnHeaderMapper;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.basic.util.enums.SystemModuleEnum;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.wms.service.across.CallbackService;
import com.wzdigit.wms.wms.service.core.GdnCoreService;
import com.wzdigit.wms.wms.service.core.transfer.TransferHeaderService;
import com.wzdigit.wms.wms.service.core.trsn.TrsnHeaderService;
import com.wzdigit.wms.wms.service.transfer.GdnCtnrService;
import com.wzdigit.wms.wms.service.transfer.TransferTaskService;
import com.wzdigit.wms.wms.strategy.webservice.handle.SendWebServiceHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.listener.Topic;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 接口中间表-数据回传 服务实现类
 * </p>
 *
 * @author
 * @since 2021-03-11
 */
@Service
@Slf4j
public class IfPostbackService {

    @Autowired
    IfPostbackMapper ifPostbackMapper;

    @Autowired
    SendWebServiceHandle sendWebServiceHandle;

    @Autowired
    @Lazy
    TransferTaskService transferTaskService;

    @Autowired
    TransferHeaderService transferHeaderService;

    @Autowired
    GdnCtnrService gdnCtnrService;

    @Autowired
    TrsnHeaderService trsnHeaderService;

    @Autowired
    GdnCoreService gdnCoreService;


    @Autowired
    @Lazy
    CallbackService callbackService;

    @Autowired
    AsnHeaderMapper asnHeaderMapper;

    /**
     * 新增一条记录
     *
     * @param ifPostback
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW)
	public Integer addOne(IfPostback ifPostback) {
		ifPostback.setCreateTime(new Date()).setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
		int row = ifPostbackMapper.insert(ifPostback);
		return row;
	}


    /**
     * 更新一条记录
     *
     * @param ifPostback
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW)
    public Integer updateOne(IfPostback ifPostback) {
        int row = ifPostbackMapper.updateById(ifPostback);
        return row;
    }


    /**
     * 查询数据回传表，获取待回写的数据
     *
     * @return
     */
    public List<IfPostback> selectSendWebServiceDatas() {

        //获取原材料回传的枚举集合
        List<String> topicList = TopicEnum.getEnumNameBySystemModule(SystemModuleEnum.RAW);
        //创建类型的条件构造器
        QueryWrapper<IfPostback> queryWrapper = new QueryWrapper<>();
        //queryWrapper.eq("POSTBACK_RESULT", BackResultEnum.DEFAULT_STATE.getCode());
        queryWrapper.eq("POSTBACK_RESULT", BackResultEnum.DEFAULT_STATE.getCode());
        queryWrapper.
                or(wrapper->wrapper.eq("POSTBACK_RESULT", BackResultEnum.BUSINESS_FAIL_STATE.getCode()).in("POSTBACK_TOPIC",topicList));

        List<IfPostback> ifPostbackList = ifPostbackMapper.selectList(queryWrapper);
        return ifPostbackList;

    }

    /**
     * 测试方法
     */
    @Deprecated
//    @Transactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = RuntimeException.class)
    public void testAddNew() {

        IfPostback ifPostback = new IfPostback();
        ifPostback.setCreateTime(new Date());
        ifPostback.setPostbackNo("test");//送检单号
        ifPostback.setDestSystem("test");
        ifPostback.setPostbackTopic("TEST");

        ifPostbackMapper.insert(ifPostback);


        System.out.println(ifPostback);
        System.out.println(ifPostback.getIfPostbackId());

        try {
            //update
            IfPostback ifPostbackUpdate = new IfPostback();
            ifPostbackUpdate.setIfPostbackId(ifPostback.getIfPostbackId());

            ifPostbackUpdate.setPostbackNo("try里面");
            ifPostbackMapper.updateById(ifPostbackUpdate);

            //模拟异常
            //TODO 测试代码，测试和投产记得删除
            int a = 0 / 0;

        } catch (Exception e) {


            IfPostback ifPostbackUpdate = new IfPostback();
            ifPostbackUpdate.setIfPostbackId(ifPostback.getIfPostbackId());

            ifPostbackUpdate.setPostbackNo("cache里面");
            ifPostbackMapper.updateById(ifPostbackUpdate);


//            throw e;
            throw new RuntimeException("他喵的出异常了");
        }
    }

    /**
     * 这个类方法冗余了，但是不理了
     *
     * @param ifPostback
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW)
    public Integer addCheckOne(IfPostback ifPostback) {
        int row = ifPostbackMapper.insert(ifPostback);
        return row;
    }

    /**
     * 查询数据回传信息
     *
     * @param requestQueryer
     * @param servletRequest
     * @param servletResponse
     */
    public PagerInfo<List<IfPostback>> search(Queryer<PostbackRequest> requestQueryer, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {

        PostbackRequest request = requestQueryer.getRequest();

        if (request.getCreateTimeStartLong() != null) {
            request.setCreateTimeStart(new Date(request.getCreateTimeStartLong()));
        }

        if (request.getCreateTimeEndLong() != null) {
            request.setCreateTimeEnd(new Date(request.getCreateTimeEndLong()));
        }

        if (request.getPostbackTimeStartLong() != null) {
            request.setPostbackTimeStart(new Date(request.getPostbackTimeStartLong()));
        }

        if (request.getPostbackTimeEndLong() != null) {
            request.setPostbackTimeEnd(new Date(request.getPostbackTimeEndLong()));
        }

        Pager<?> page = requestQueryer.getPage();

        // page为空，默认最大分页
        if (page == null) {
            page = new Pager<IfPostback>();
            page.setSkipCount(0);
            page.setMaxResultCount(Integer.MAX_VALUE);
        }

        PagerInfo<List<IfPostback>> info = new PagerInfo<>();

        try {
            Page<IfPostback> _page = PageHelper.offsetPage(page.getSkipCount(), page.getMaxResultCount());

            PageInfo<IfPostback> result = new PageInfo<>(_page);

            List<IfPostback> ifPostbackList = ifPostbackMapper.search(request);

            result.setList(ifPostbackList);
            info.setTotalCount(_page.getTotal());// 总数
            info.setItems(result.getList());// 返回结果
        } catch (Exception ex) {
            ex.printStackTrace();
            Shift.fatal(StatusCode.SERVER_MODIFY_ERROR);
        }
        return info;


    }

    /**
     * 重发报文
     *
     * @param ifPostbackId
     * @param servletRequest
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<IfPostback> reSend(Integer ifPostbackId, HttpServletRequest servletRequest) {

        IfPostback ifPostback = ifPostbackMapper.selectById(ifPostbackId);


        String sapSendCheckEnumName = TopicEnum.TOPIC_SAP_SEND_CHECK.getEnumName();
        if (ifPostback.getPostbackTopic().equals(sapSendCheckEnumName)) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "报检功能走翻牌，此处不重复推送");
        }

        Integer postbackResult = ifPostback.getPostbackResult();
        int successStateCode = BackResultEnum.BUSINESS_SUCCESS_STATE.getCode();
        if (postbackResult.equals(successStateCode)) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "成功返回的报文不能重复发送");
        }

        String topic = ifPostback.getPostbackTopic();

        TopicEnum topicEnum = TopicEnum.getEnumByName(topic);
        //发送报文请求，并更新【数据回传表】
        Object send = sendWebServiceHandle.send(topicEnum, ifPostback);

        //再次查询
        ifPostback = ifPostbackMapper.selectById(ifPostbackId);
        Result<IfPostback> result = new Result<>();
        result.setData(ifPostback);
        return result;
    }

    /**
     * 重新生成新的一条报文
     *
     * @param ifPostbackId
     * @param servletRequest
     * @return
     */
    //TODO 后面用策略改下
    @Transactional(rollbackFor = Exception.class)
    public Result<IfPostback> reBiuld(Integer ifPostbackId, HttpServletRequest servletRequest) throws Exception {

        IfPostback ifPostback = ifPostbackMapper.selectById(ifPostbackId);

        if (TopicEnum.TOPIC_TMS_TAKE_OVER.getEnumName().equals(ifPostback.getPostbackTopic())){
            Shift.fatal("该报文不能重新生成!");
        }

        Integer postbackResult = ifPostback.getPostbackResult();

        int businessFailStateCode = BackResultEnum.BUSINESS_FAIL_STATE.getCode();
        int systemErrorStateCode = BackResultEnum.SYSTEM_ERROR_STATE.getCode();

        if (!(postbackResult.equals(businessFailStateCode) || postbackResult.equals(systemErrorStateCode))) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "非异常/失败的回参报文不能重新生成");
        }

        String postbackTopic = ifPostback.getPostbackTopic();
        String postbackType = ifPostback.getPostbackType();
        String postbackNo = ifPostback.getPostbackNo();
        String loginName = HttpSessionUtil.getLoginName(servletRequest);

        Integer newPk = null;
        //TODO 构建新的报文
        if (postbackTopic.equals(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName())) {
            if (ifPostback.getPostbackType().equals(GdnTypeEnum.D99.getCode())) {
                //TODO
//                GdnHeader gdnHeader = gdnCtnrService.getGdnHeaderByGdnNo(postbackNo);
                GdnHeader gdnHeader = gdnCoreService.getGdnHeaderByGdnNo(postbackNo);

                String json = callbackService.create_D99_JSON(gdnHeader);

                IfPostback ifPostbackUpdate = new IfPostback();
                ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
                ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

                ifPostbackUpdate.setCreateTime(new Date());
                ifPostbackUpdate.setCreateUser(loginName);
                ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
                ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
                ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
                ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
                ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID
                ifPostbackUpdate.setPostbackContent(json);

                Integer row = this.addOne(ifPostbackUpdate);
                log.info("成功新增{}条记录", row);

                newPk = ifPostbackUpdate.getIfPostbackId();

            } else if(ifPostback.getPostbackType().equals(AsnTypeEnum.R99.getCode())){
                //创建类型的条件构造器

                //创建类型的条件构造器
                QueryWrapper<AsnHeader> wrapper = new QueryWrapper<>();
                wrapper.eq("ASN_NO", postbackNo);
                AsnHeader asnHeader = asnHeaderMapper.selectOne(wrapper);

//                String json = callbackService.create_R09_JSON(asnHeader);
                String json = callbackService.create_R99_JSON(asnHeader);

                IfPostback ifPostbackUpdate = new IfPostback();
                ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
                ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

                ifPostbackUpdate.setCreateTime(new Date());
                ifPostbackUpdate.setCreateUser(loginName);
                ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
                ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
                ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
                ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
                ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID
                ifPostbackUpdate.setPostbackContent(json);

                Integer row = this.addOne(ifPostbackUpdate);
                log.info("成功新增{}条记录", row);

                newPk = ifPostbackUpdate.getIfPostbackId();

            } else if (ifPostback.getPostbackType().startsWith("T")) {
                //SAP_调拨单
                TransferHeader transferHeader = transferHeaderService.getByTransferNo(postbackNo);

                IfPostback ifPostbackUpdate = transferTaskService.insertIfpostbackList(loginName, transferHeader, postbackType);
                ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID
                Integer row = this.addOne(ifPostbackUpdate);

                log.info("成功新增{}条记录", row);
                newPk = ifPostbackUpdate.getIfPostbackId();

            }

        } else if (postbackTopic.equals(TopicEnum.TOPIC_SAP_DELIVERY.getEnumName())) {

            if (ifPostback.getPostbackType().equals(AsnTypeEnum.R04.getCode())) {
                //销售退货回写SAP
                IfPostback ifPostbackUpdate = new IfPostback();
                ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
                ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

                ifPostbackUpdate.setCreateTime(new Date());
                ifPostbackUpdate.setCreateUser(loginName);
                ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
                ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
                ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
                ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
                ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID

//                String postbackContent = gdnCtnrService.getGdnDataWithSap(postbackNo);
                //创建类型的条件构造器
                QueryWrapper<AsnHeader> wrapper = new QueryWrapper<>();
                wrapper.eq("ASN_NO", postbackNo);
                AsnHeader asnHeader = asnHeaderMapper.selectOne(wrapper);

                String r04Json = callbackService.create_R04_JSON(asnHeader);
                ifPostbackUpdate.setPostbackContent(r04Json);

                Integer row = this.addOne(ifPostbackUpdate);
                log.info("成功新增{}条记录", row);

                newPk = ifPostbackUpdate.getIfPostbackId();

            } else {
                //点击“结束装运并关单”按钮
                //SAP_交货单
                IfPostback ifPostbackUpdate = new IfPostback();
                ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
                ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

                ifPostbackUpdate.setCreateTime(new Date());
                ifPostbackUpdate.setCreateUser(loginName);
                ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
                ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
                ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
                ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
                ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID

                String postbackContent = gdnCtnrService.getGdnDataWithSap(postbackNo);
                ifPostbackUpdate.setPostbackContent(postbackContent);

                Integer row = this.addOne(ifPostbackUpdate);
                log.info("成功新增{}条记录", row);

                newPk = ifPostbackUpdate.getIfPostbackId();
            }

        } else if (postbackTopic.equals(TopicEnum.TOPIC_OMS_ACTUAL_CTNR.getEnumName())) {
            //OMS_实际装柜清单
            IfPostback ifPostbackUpdate = new IfPostback();
            ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
            ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

            ifPostbackUpdate.setCreateTime(new Date());
            ifPostbackUpdate.setCreateUser(loginName);
            ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
            ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
            ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
            ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
            ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID

            String postbackContent = gdnCtnrService.getGdnDataWithOms(postbackNo);
            ifPostbackUpdate.setPostbackContent(postbackContent);

            Integer row = this.addOne(ifPostbackUpdate);
            log.info("成功新增{}条记录", row);

            newPk = ifPostbackUpdate.getIfPostbackId();
        } else if (postbackTopic.equals(TopicEnum.TOPIC_SAP_WAIT_CHECK_IN_INSTORAGE.getEnumName()) && ifPostback.getPostbackType().equals(AsnTypeEnum.R09.getCode())) {
            //公司间交货入库
            IfPostback ifPostbackUpdate = new IfPostback();
            ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
            ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

            ifPostbackUpdate.setCreateTime(new Date());
            ifPostbackUpdate.setCreateUser(loginName);
            ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
            ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
            ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
            ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
            ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID


            //创建类型的条件构造器
            QueryWrapper<AsnHeader> wrapper = new QueryWrapper<>();
            wrapper.eq("SOURCE_NO", ifPostback.getPostbackSourceNo());
            AsnHeader asnHeader = asnHeaderMapper.selectOne(wrapper);
            String postbackContent = callbackService.create_R09_JSON(asnHeader);

//            String postbackContent = gdnCtnrService.getGdnDataWithOms(postbackNo);
            ifPostbackUpdate.setPostbackContent(postbackContent);


            Integer row = this.addOne(ifPostbackUpdate);
            log.info("成功新增{}条记录", row);

            newPk = ifPostbackUpdate.getIfPostbackId();
        } else if (postbackTopic.equals(TopicEnum.TOPIC_SAP_MATERIAL_WRITE_BACK.getEnumName()) && ifPostback.getPostbackType().equals(GdnTypeEnum.D03.getCode()) ){
            //SAP_领料回写
            IfPostback ifPostbackUpdate = new IfPostback();
            ifPostbackUpdate.setDestSystem(ifPostback.getDestSystem());
            ifPostbackUpdate.setPostbackTopic(ifPostback.getPostbackTopic());

            ifPostbackUpdate.setCreateTime(new Date());
            ifPostbackUpdate.setCreateUser(loginName);
            ifPostbackUpdate.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
            ifPostbackUpdate.setPostbackNo(ifPostback.getPostbackNo());
            ifPostbackUpdate.setPostbackSourceNo(ifPostback.getPostbackSourceNo());
            ifPostbackUpdate.setPostbackType(ifPostback.getPostbackType());
            ifPostbackUpdate.setRePostbackId(ifPostbackId);//重传ID


            //创建类型的条件构造器
            //create_D03_JSON
            List<String> splitList = Arrays.asList(postbackNo.split("\\$"));

            String gdnNo = splitList.get(0);
            String trsnNoteNo = splitList.get(1);

//            GdnHeader gdnHeader = gdnCtnrService.selectBySourceShipNotice(ifPostback.getPostbackSourceNo());
            GdnHeader gdnHeader = gdnCoreService.selectBySourceShipNotice(ifPostback.getPostbackSourceNo());

//            String gdnNo = gdnHeader.getGdnNo();
            TrsnHeader trsnHeader = trsnHeaderService.selectByFmDocAndNoteNo(gdnNo,trsnNoteNo);

            String postbackContent = callbackService.create_D03_JSON(gdnHeader,trsnHeader);

//            String postbackContent = gdnCtnrService.getGdnDataWithOms(postbackNo);
            ifPostbackUpdate.setPostbackContent(postbackContent);
            Integer row = this.addOne(ifPostbackUpdate);
            log.info("成功新增{}条记录", row);

            newPk = ifPostbackUpdate.getIfPostbackId();

        } else {
            Shift.fatal(StatusCode.BUSINESS_ERR, "未查询到对应的回传主题");
        }

//        IfPostback ifPostbackReBuild = new IfPostback();
//        ifPostbackReBuild.setRePostbackId(ifPostbackId);

        IfPostback ifPostbackReturn = ifPostbackMapper.selectById(newPk);

        Result<IfPostback> result = new Result<>();
        result.setData(ifPostbackReturn);
        return result;
    }
}